package cshi.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 * 线程与任务有不同的概念，一般说：线程驱动任务
 * 优先级不会导致死锁，优先级低的线程仅仅是执行的频率较低
 * 后台线程并不属于程序中的不可或缺的部分，因此当所有的非后台线程结束时，程序也就终止了，同时会杀死所有的后台线程；反过来
 * 	说只要有任何非后台线程还在运行，程序就不会终止，例如main.setDaemon一定要在线程启动之前调用。后台线程创建的任何
 * 	线程都自动成后台线程！
 * 
 * 后台线程不执行finally子句的情况下就会终止其run方法，你不能以优雅的方式来关闭后台线程
 * 
 * 对特定对象来说，其所有synchronized方法共享一个锁！即意味着一个任务在访问synchronized方法时，其他任务对于
 * 所有synchronized方法都得等待锁释放
 * 
 * 同步也会导致向主存中刷新，因此一个域完全由synchronized方法或语句块来保护，那就不必设置为volatile.volatile
 * 	并不能对递增不是原子性操作这一事实产生影响
 * 
 * AtomicInteger等类型在性能调优时，就很有用，尽量在特殊情况下才使用它们
 * 
 * 两个任务可以同时进入同一个对象，只要这个对象上的方法是在不同的锁上同步即可（TIJ page 689）
 * 
 * ThreadLocal是线程本地存储对象，为每个不同的线程创建不同的存储
 * jvm不区分主线程和用户线程，各个线程是独立的，不同与win32的线程模型。
 * jvm把线程分为前台线程和后台线程，后台线程官方术语叫守护线程
 */

class MyThread2 implements Runnable{
	private int ticket = 5;
	@Override
	public synchronized void run() {
		for (int i=0; i<10000; i++){
			//synchronized (this) {
				if (ticket > 0){
					//异常不能跨线程，所以必须在本地处理内部异常
					try {
						Thread.sleep(300);
					} catch (Exception e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + 
							":ticket=" + ticket--);
				}
			//}
			
		}
		
	}
	
}

public class Test {
	public static void testMyThread() {
		MyThread2 mt = new MyThread2();
		Thread t1 = new Thread(mt);
		Thread t2 = new Thread(mt);
		Thread t3 = new Thread(mt);
		
		t2.start();t1.start();t3.start();
	}
	
	public static void useExecutor() {
		ExecutorService es = Executors.newCachedThreadPool();
		for (int i=0; i<5; i++)
			es.execute(new MyThread2());
		es.shutdown();
	}
	public static void main(String[] args) throws Exception{
		testMyThread();
		//useExecutor();
		
		
	}
}
